/*
 * @Author: wz
 * @Date: 2020-11-25 16:38:41
 * @LastEditors: wz
 * @LastEditTime: 2021-01-29 15:02:39
 * @Description:通用函数
 */

import _ from 'lodash'
export const createNewParams = params => {
    let pam = {}
    for (let key in params) {
        if (!_.isEmpty(params[key])) {
            pam[key] = params[key]
        }
    }
    return pam
}

// 语言方面的辅助函数
// 判断变量是否为数组
function isArray(v) {
    return Object.prototype.toString.call(v) === '[object Array]'
}

function isObject(v) {
    return Object.prototype.toString.call(v) === '[object Object]'
}

function isFunction(v) {
    return Object.prototype.toString.call(v) === '[object Function]'
}

function isString(v) {
    return Object.prototype.toString.call(v) === '[object String]'
}

function isNumber(v) {
    return Object.prototype.toString.call(v) === '[object Number]'
}

let o = {
    isArray,
    isObject,
    isFunction,
    isString,
    isNumber,
    ORGTYPE: 6 // 布行ERP，机构类型
}

/**
 * 简单解决数据精度问题
 * 根本解决需要全局修改计算处理
 * num ==> 需处理的数据
 * n ==> 保留多少位小数
 */
o.toFixed = (num, n = 0) => {
    num = (Number(num) || 0) + ''
    let arr = num.split('.')
    let str = ''
    if (arr.length >= 2) {
        str = `${arr[0]}.${arr[1].substr(0, n)}`
    } else {
        str = arr[0]
        if (n > 0) {
            str += '.'
            for (let i = 0; i < n; i++) {
                str += '0'
            }
        }
    }
    // console.log('o.toFixed', str)
    return n > 0 ? parseFloat(str).toFixed(n) : parseInt(str)
}

// 千分位变回数字
o.qian_Num = function (val) {
    return Number((val + '').replace(/[^\d\.-]/g, ''))
}

/**
 * 获取当前登录人信息
 */
o.getUserInfo = () => {
    let userInfo = localStorage.getItem('userInfo') ? JSON.parse(localStorage.getItem('userInfo')) : {}
    return userInfo
}

/**
 * 传入的参数是0-9的时候，返回00-09
 * @param {string | number} 必须是一个数字
 */
o.formatNumber = n => {
    const str = n.toString()
    return str[1] ? str : `0${str}`
}

/**
 * 传入一个时间格式（如 new Date()）返回特定的时间格式
 * @param {date} date
 */
o.formatTime = function (date) {
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()

    const hour = date.getHours()
    const minute = date.getMinutes()
    const second = date.getSeconds()

    const t1 = [year, month, day].map(this.formatNumber).join('-')
    const t2 = [hour, minute, second].map(this.formatNumber).join(':')

    return `${t1} ${t2}`
}

/**
 * 重复decodeURIComponent，解析被多次encodeURIComponent的链接
 * @param {string} url链接
 */
o.loopDecodeURIComponent = url => {
    const urlReg = /^https?:\/\//
    let count = 4

    while (count-- && !urlReg.test(url)) {
        url = decodeURIComponent(url)
    }

    return url
}

/**
 * 动态加载JS文件
 * @param {string} url 加载的URL
 * @param {function} callback 加载成功后的回调函数
 */
o.loadScript = (url, callback) => {
    var script = document.createElement('script')
    script.type = 'text/javascript'
    script.onload = function () {
        script.onload = null
        callback()
    }

    script.src = url
    document.getElementsByTagName('head')[0].appendChild(script)
}

/**
 * 设置/计算上下文值
 * @param  {*}       context 上下文对象。
 * @param  {String}  exp     字段表达式，以'.'和'[\d+]'分割成字段的访问堆栈
 * @param  {*}       [val]     要设置的值，不传时为get模式。
 * @return {*}  get模式下才会返回
 *
 * @example
 *  var data = { asd: ={qwe: 123} };
 *  parseExp(data, 'asd.qwe', 789); // 设置对象内的qwe为789
 *  parseExp(data, 'asd.qwe'); // 获取对象内qwe的值
 */
o.parseExp = (context, exp, val) => {
    const chain = exp
        .replace(/^\[(\d+)\]/, '$1')
        .replace(/\[(\d+)\]/g, '.$1')
        .split('.')
    let last_key

    if (context && exp && val) {
        last_key = chain.pop()
    }

    for (let i = 0; i < chain.length; i++) {
        if (!context) return
        context = context[chain[i]]
    }

    if (last_key) {
        context[last_key] = val
    } else {
        return context
    }
}

/**
 * 格式化千位数
 * @param {*} num 一个数字
 */
o.toThousands = num => {
    const suffix = num.toString().match(/\.[\s\S]*/)

    if (!num) {
        return 0
    } else {
        return (
            Math.floor(num)
                .toString()
                .replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') + (suffix ? suffix[0] : '')
        )
    }
}

/**
 * 格式化数字
 * @param  {Number} num       要格式化的数字
 * @param  {Object} unitSheet 数字单位的参考表。
 * @example
 * formatCount(12, unitSheet); // 12
 * formatCount(1234, unitSheet); // 1.2k
 * formatCount(123456, unitSheet); // 12w
 */
o.formatCount = (num, unitSheet) => {
    let _unitSheet = {
        4: {
            unit: 'k', // 单位
            start: 4 // 多少位起计
        },
        5: 'w'
    }

    unitSheet = unitSheet || _unitSheet

    var bitOfVal,
        _bit,
        _bitObj,
        formatBit,
        unitSheetKeys = Object.keys(unitSheet)

    num = Math.floor(+num)
    bitOfVal = (num + '').length

    for (var i = unitSheetKeys.length - 1; i >= 0; i--) {
        _bit = unitSheetKeys[i]
        _bitObj = unitSheet[_bit]
        _bit = typeof _bitObj === 'object' ? _bitObj.start : _bit

        if (bitOfVal >= _bit) {
            formatBit = unitSheetKeys[i]
            break
        }
    }

    if (formatBit) {
        return +(num / Math.pow(10, formatBit - 1)).toFixed(1) + (unitSheet[formatBit].unit || unitSheet[formatBit])
    }

    return num
}

/**
 * 深度克隆对象
 * @param {object} origin 入参是一个对象
 */
o.clone = origin => {
    let originProto = Object.getPrototypeOf(origin) // 获取对象原型链
    let createOrigin = Object.create(originProto) // 创建一个原型为originProto的新对象
    return Object.assign(createOrigin, origin) // 把origin对象的数据复杂到新对象上
}

/**
 * 获取url的参数
 * @param {string} name 字符串
 */
o.getQueryString = name => {
    var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
    var r = ''
    if (window.location.search) {
        r = window.location.search.substr(1).match(reg)
    } else {
        r = window.location.href.split('?')[1] && window.location.href.split('?')[1].match(reg)
    }
    if (r != null) return unescape(r[2])
    return null
}

/**
 * 传入yyyy-mm-dd hh:mm:ss的时间格式，返回时间戳
 * @param {string} time
 */
o.timeStamp = time => {
    let times = time.split(' ')
    let ymd = times[0].split('-')
    let hms = times[1].split(':')
    return new Date(ymd[0], ymd[1], ymd[2], hms[0], hms[1], hms[2]).getTime()
}

/**
 * 时间格式化
 */
o.formatTimeString = (time, format) => {
    var format1 = format || 'yyyy-MM-dd'
    var t = new Date(time)
    var tf = function (i) {
        return (i < 10 ? '0' : '') + i
    }
    return format1.replace(/yyyy|MM|dd|HH|mm|ss/g, function (a) {
        switch (a) {
            case 'yyyy':
                return tf(t.getFullYear())
            case 'MM':
                return tf(t.getMonth() + 1)
            case 'mm':
                return tf(t.getMinutes())
            case 'dd':
                return tf(t.getDate())
            case 'HH':
                return tf(t.getHours())
            case 'ss':
                return tf(t.getSeconds())
        }
    })
}

// 请求下载接口, 实现下载
o.downloadExcel = obj => {
    // let path = obj.path
    // let params = obj.params
    // let userInfo = JSON.parse(localStorage.getItem('userInfo')) || {}
    // params.factoryId = userInfo.factoryId
    // params.orgCode = userInfo.orgCode
    // params.workerId = userInfo.workId
    // params.loginUserCode = userInfo.loginUserCode
    // // 生成键值对数组 ['key1=value1', 'key2=value2']
    // let queryArr = Object.keys(params).map((key) => {
    //   return (key + '=' + params[key])
    // })
    // // 拼接参数
    // let url = path + '?' + queryArr.join('&')
    // return new Promise(function (resolve, reject) {
    //   axios({
    //     method: 'get',
    //     url: url,
    //     responseType: 'blob'
    //   }).then(response => {
    //     let fileName = obj.fileName + '.xlsx'
    //     // let headers = response.headers
    //     // let fileName = headers['content-disposition'].split('=')[1]
    //     // fileName = decodeURIComponent(fileName)
    //     let dowloadUrl = window.URL.createObjectURL(new Blob([response.data]))
    //     let link = document.createElement('a')
    //     link.style.display = 'none'
    //     link.href = dowloadUrl
    //     link.setAttribute('download', fileName)
    //     document.body.appendChild(link)
    //     link.click()
    //     resolve()
    //   }).catch((error) => {
    //     Message.error('导出报表数据出错')
    //     reject(error)
    //   })
    // })
}

// 筛选小数或正式等
o.numberFormat = (num, type) => {
    if (num) {
        num = num + ''
        num = num.replace(/^\./, '') // 如果第一个字符串是“.”要去掉
        num = num.replace(/[^\d.]/g, '') // 清除"数字"和"."以外的字符
        if (num.indexOf('.') > -1) {
            // 只保留第一个.清除多余的
            let a = num.split('.')
            num = a[0] + '.' + a[1]
        }
        if (type === 'amount') num = num.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能输入两个小数
        if (num === '') return ''
        // 如果要取整数就要执行if语句
        if (type === 'integer') num = parseInt(num, 10)
        return num
    }
    return num
}

// 对象遍历，并返回一个数组
o.mapsWalk = (maps, handler) => {
    var key
    var res
    var arr = []
    for (key in maps) {
        res = handler(key, maps[key], maps)
        if (res !== undefined) {
            arr.push(res)
        }
    }
    return arr
}

// 查询条件格式化
o.conditionsFormator = (querys, filters) => {
    filters = filters || {}
    return o.mapsWalk(querys, function (key, val, obj) {
        if (val === '' || val === null || val === undefined) return
        var res = {}
        res.attributeName = key
        res.rangeType = filters[key] ? filters[key] : 'EQUAL'
        // res.rangeType = filters[key] || ''
        res.targetValue = isArray(val) ? val : [val]
        return res
    })
}

//
/**
 * 校验两位小数点正数
 * 案例：
 * import { numberFormat } from 'utils/utils'
 * checkNumber (e, item, type, length) { item[type] = numberFormat(e) },
 * <el-input  @input="checkNumber($event, materialForm, 'dtex', 7)" :value="materialForm.dtex" ></el-input>
 */
o.numberFormat = (num, type) => {
    if (num) {
        num = num + ''
        num = num.replace(/^\./, '') // 如果第一个字符串是“.”要去掉
        num = num.replace(/[^\d.]/g, '') // 清除"数字"和"."以外的字符
        if (num.indexOf('.') > -1) {
            // 只保留第一个.清除多余的
            let a = num.split('.')
            num = a[0] + '.' + a[1]
        }
        num = num.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能输入两个小数
        if (num === '') {
            return ''
        }
        // 如果要取整数就要执行if语句
        if (type === 'integer') {
            num = parseInt(num, 10)
        }
        return num
    }
    return num
}
// 四舍五入 num为传入的值，n为保留的小数位
o.fomatFloat = (num, n) => {
    var f = parseFloat(num)
    if (isNaN(num) || isNaN(f)) return false
    // if(isNaN(f)){
    //     return false
    // }
    f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n) // n 幂
    var s = f.toString()
    var rs = s.indexOf('.')
    //判定如果是整数，增加小数点再补0
    if (rs < 0) {
        rs = s.length
        s += '.'
    }
    while (s.length <= rs + n) {
        s += '0'
    }
    return s
}
;(o.pad = number => {
    return number < 10 ? '0' + number : '' + number // 小于10补上0
}),
    (o.dateParams = timeStamp => {
        let date = {}
        let time = new Date(timeStamp)
        date.year = time.getFullYear()
        date.month = o.pad(time.getMonth() + 1)
        date.date = o.pad(time.getDate())
        date.hour = o.pad(time.getHours())
        date.minute = o.pad(time.getMinutes())
        date.second = o.pad(time.getSeconds())
        return date
    })
o.formatDate = (timeStamp, connector, format) => {
    let _ = connector instanceof String ? connector : String(connector)
    let date = o.dateParams(timeStamp)
    let date_ = {
        year: date.year,
        month: date.year + _ + date.month,
        date: date.year + _ + date.month + _ + date.date,
        hour: date.year + _ + date.month + _ + date.date + ' ' + date.hour,
        minute: date.year + _ + date.month + _ + date.date + ' ' + date.hour + ':' + date.minute,
        second: date.year + _ + date.month + _ + date.date + ' ' + date.hour + ':' + date.minute + ':' + date.second,
        chinese: date.year + '年' + date.month + '月' + date.date + '日',
        chineseTime: date.year + '年' + date.month + '月' + date.date + '日' + ' ' + date.hour + '时' + date.minute + '分' + date.second + '秒'
    }
    return date_[format]
}
/**
 * 返显字典值
 */
o.numberFormat = (num, type) => {
    if (num) {
        num = num + ''
        num = num.replace(/^\./, '') // 如果第一个字符串是“.”要去掉
        num = num.replace(/[^\d.]/g, '') // 清除"数字"和"."以外的字符
        if (num.indexOf('.') > -1) {
            // 只保留第一个.清除多余的
            let a = num.split('.')
            num = a[0] + '.' + a[1]
        }
        num = num.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能输入两个小数
        if (num === '') {
            return ''
        }
        // 如果要取整数就要执行if语句
        if (type === 'integer') {
            num = parseInt(num, 10)
        }
        return num
    }
    return num
}

o.backDict = (options, val, cn_key = 'label') => {
    // console.log(options, val)
    let label = options.filter(item => item.value == val)
    label = label.length ? label[0][cn_key] : ''
    return label
}
/**
 * 数值千分位格式化
 * num -> 数值
 * isZ -> 是否取整
 */
o.numFormat = (num, isZ) => {
    let s = (isZ ? Math.round(num) + '' : num.toFixed(2) + '').replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
    console.log(s)
    return s
}
o.createParams = function (params) {
    // let params = {
    //   rangeData: {
    //     itemName: "INCLUDE",
    //     itemType: 'EQUAL'
    //   },
    //   orderBy: [
    //     {
    //       attributeName: "createTime",
    //       rankType: "DESC"
    //     }
    //   ],
    //   itemName: val || '', // 客户名称
    //   itemType: '1'
    // }
    let o = {}
    this.mapsWalk(params, (key, val, obj) => {
        if (['pageSize', 'pageNO', 'rangeData', 'orderBy'].indexOf(key) === -1) {
            o[key] = val
        }
    })
    return {
        pageNO: params.pageNO,
        pageSize: params.pageSize,
        orderBy: params.orderBy,
        conditions: this.conditionsFormator(o, params.rangeData)
    }
}
/**
 * 生成列表页查询参数
 * data -> 对象
 */
o.generateListPageParams = data => {
    let object = {}
    o.mapsWalk(data, (key, val, obj) => {
        if (['pageSize', 'pageNO', 'rangeData', 'orderBy'].indexOf(key) === -1) {
            object[key] = val
        }
    })
    let params = {
        pageSize: data.pageSize,
        pageNO: data.pageNO,
        orderBy: data.orderBy,
        conditions: o.conditionsFormator(object, data.rangInfo ? data.rangInfo : data.rangeData)
    }
    return params
}

/**
 * 引用类型数组去重
 * @param list --> [{}, {}]
 * @param keyName --> 比较的唯一参数
 */
o.listObjsReduce = (list, keyName) => {
    let hash = {}
    list = list.reduce(function (item, next) {
        let attr = next[keyName]
        hash[attr] ? '' : (hash[attr] = true && item.push(next))
        return item
    }, [])
    return list
}

export default o
